package com.sybil.spa.servicio;

import com.sybil.spa.dominio.Usuario;
import java.util.Collections;
import java.util.List;
import javax.naming.NamingException;
import javax.naming.directory.Attributes;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.ldap.core.AttributesMapper;
import org.springframework.ldap.core.LdapTemplate;
import org.springframework.ldap.filter.AndFilter;
import org.springframework.ldap.filter.EqualsFilter;
import org.springframework.ldap.filter.LikeFilter;
import org.springframework.ldap.filter.PresentFilter;
import org.springframework.stereotype.Service;

@Service
public class UsuarioServicio {

   @Autowired
   private LdapTemplate ldapTemplate;

   public void setLdapTemplate(LdapTemplate ldapTemplate) {
      this.ldapTemplate = ldapTemplate;
   }

   public Usuario getUsuario(String username) {
      AndFilter filter = new AndFilter();
      filter.and(new EqualsFilter("sAMAccountName", username));
      filter.and(new EqualsFilter("objectClass", "user"));
      List lista = ldapTemplate.search("", filter.encode(), new PersonAttributesMapper());
      if (lista != null && !lista.isEmpty()) {
         Usuario usuario = (Usuario) lista.get(0);
         if (usuario != null && usuario.getJefe() != null && usuario.getJefe().getClave() != null
                 && !usuario.getJefe().getClave().equals("")) {
            usuario.setJefe(getJefeUsuario(usuario.getJefe().getClave()));
         }
         return usuario;
      } else {
         return null;
      }
   }

   public String getNombreUsuario(String username) {
      AndFilter filter = new AndFilter();
      filter.and(new EqualsFilter("sAMAccountName", username));
      filter.and(new EqualsFilter("objectClass", "user"));
      List l = ldapTemplate.search("", filter.encode(), new AttributesMapper() {
         @Override
         public Object mapFromAttributes(Attributes atributos) throws NamingException {
            return (atributos.get("givenname") != null
                    ? atributos.get("givenname").get(0).toString()
                    : "") + " " + (atributos.get("sn") != null
                    ? atributos.get("sn").get(0).toString()
                    : "");
         }
      });
      if (l != null && !l.isEmpty()) {
         return l.get(0).toString();
      } else {
         return null;
      }
   }

   private Usuario getJefeUsuario(String distinguishedname) {
      AndFilter filter = new AndFilter();
      filter.and(new EqualsFilter("distinguishedname", distinguishedname));
      filter.and(new EqualsFilter("objectClass", "user"));
      List lista = ldapTemplate.search("", filter.encode(), new PersonAttributesMapper());
      if (lista != null && !lista.isEmpty()) {
         return (Usuario) lista.get(0);
      } else {
         return null;
      }
   }

   public List<Usuario> getUsuarios() {
      List lista = getUsuarios("A");
      for (int i = 66; i < 91; i++) {
         String letra = "" + (char) i;
         lista.addAll(getUsuarios(letra));
      }
      if (lista != null && !lista.isEmpty()) {
         Collections.sort(lista);
         return lista;
      } else {
         return null;
      }
   }

   private List<Usuario> getUsuarios(String letra) {
      AndFilter filter = new AndFilter();
      filter.and(new EqualsFilter("objectClass", "user"));
//      filter.and(new EqualsFilter("objectCategory", "Person"));
      filter.and(new PresentFilter("sn"));
      filter.and(new PresentFilter("givenname"));
      filter.and(new PresentFilter("mail"));
      filter.and(new LikeFilter("sAMAccountName", letra + "*"));
      return ldapTemplate.search("", filter.encode(), new PersonAttributesMapper());
   }

   private static class PersonAttributesMapper implements AttributesMapper {

      @Override
      public Object mapFromAttributes(Attributes atributos) throws NamingException {
         Usuario usuario = new Usuario();
         usuario.setClave(atributos.get("samaccountname").get(0).toString());
         usuario.setNombre(atributos.get("givenname") != null
                 ? atributos.get("givenname").get(0).toString()
                 : "");
         usuario.setApellidos(atributos.get("sn") != null
                 ? atributos.get("sn").get(0).toString()
                 : "");
         usuario.setEmail(atributos.get("mail") != null
                 ? atributos.get("mail").get(0).toString()
                 : "");
         usuario.setDepartamento(atributos.get("department") != null
                 ? atributos.get("department").get(0).toString()
                 : "");
         usuario.setPuesto(atributos.get("title") != null
                 ? atributos.get("title").get(0).toString()
                 : "");
         usuario.setDescripcion(atributos.get("description") != null
                 ? atributos.get("description").get(0).toString()
                 : "");
         usuario.setCompania(atributos.get("company") != null
                 ? atributos.get("company").get(0).toString()
                 : "");
         long numeroEmpleado;
         try {
            numeroEmpleado = atributos.get("postOfficeBox") != null
                    ? Long.parseLong(atributos.get("postOfficeBox").get(0).toString())
                    : 0;
         } catch (NumberFormatException e) {
            numeroEmpleado = 0;
         }
         usuario.setNumeroEmpleado(numeroEmpleado);
         usuario.setOficina(atributos.get("physicaldeliveryofficename") != null
                 ? atributos.get("physicaldeliveryofficename").get(0).toString()
                 : "");
         Usuario jefeUsuario = new Usuario();
         jefeUsuario.setClave(atributos.get("manager") != null
                 ? atributos.get("manager").get(0).toString()
                 : null);
         usuario.setJefe(jefeUsuario);
         return usuario;
      }
   }
}
